package com.nulldev.util.java.swing.extSwing;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import com.nulldev.util.java.DataSet;
import com.nulldev.util.java.swing.SwingUtil;
import com.nulldev.util.java.swing.extSwing.iNotify.Message;
import com.nulldev.util.java.swing.extSwing.iNotify.iNotify;
import com.nulldev.util.java.swing.extSwing.lookandfeel.themes.ThemeApplier;
import com.nulldev.util.java.swing.extSwing.resources.eMessageType;
import com.nulldev.util.java.swing.fastEPane.FastEditorKit;
import com.nulldev.util.other.ArrayUtils;
import com.nulldev.util.uri.nStreamHandlerFactory;
import com.nulldev.util.web.nCaptcha.nCaptcha;
import com.nulldev.util.web.nCaptcha.backend.Captcha;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JPasswordField;
import javax.swing.JEditorPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JScrollPane;
import java.awt.Toolkit;

public class eLoginPane extends JFrame {
	
	//TODO: Rewrite to match SecureLoginUI look

	private JPanel contentPane0, contentPane;
	private JTextField textField;
	private JPasswordField passwordField;
	private JEditorPane editorPane;
	private JTextField textField_1;

	/**
	 * Launch the application.
	 * @return 
	 */
	public static eLoginPane main(final eLoginPaneEvents events) {
		nStreamHandlerFactory.install();
		final eLoginPane frame = new eLoginPane(events);
		ThemeApplier.applyTheme(frame);
		frame.applyNotifyFix();
		SwingUtil.centerFrame(frame);
		frame.setVisible(true);
		return frame;
	}

	private void applyNotifyFix() {
		this.panel_2.setBackground(this.getBackground());
	}

	private final eLoginPaneEvents events;
	
	/**
	 * Create the frame.
	 */
	public eLoginPane(final eLoginPaneEvents events) {
		setIconImage(Toolkit.getDefaultToolkit().getImage(eLoginPane.class.getResource("/com/nulldev/util/java/swing/nullutil_logo.png")));
		this.events = events;
		setTitle("extSwing.eLoginPane");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 371, 385);
		contentPane = new JPanel();
		contentPane.setLayout(new BorderLayout());
		contentPane0 = new JPanel();
		contentPane0.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane0.setLayout(new BorderLayout(0, 0));
		contentPane0.add(contentPane);
		setContentPane(contentPane0);
		
		JLabel lblUsername = new JLabel("Username");
		
		textField = new JTextField();
		textField.setColumns(10);
		
		JLabel lblPassword = new JLabel("Password");
		
		passwordField = new JPasswordField();
		passwordField.setEchoChar('*');
		
		lblEloginpaneproducticon = new JLabel("eLoginPane.productIcon");
		
		panel = new JPanel();
		panel.setEnabled(false);
		panel.setVisible(false);
		
		final JButton btnExit = new JButton("Exit");
		final JButton btnLogin = new JButton("Login");
		btnLogin.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				btnLogin.setEnabled(false);
				btnExit.setEnabled(false);
				textField_1.setEnabled(false);
				textField.setEnabled(false);
				passwordField.setEnabled(false);
				final String captchaInput = textField_1.getText();
				final String login = textField.getText();
				if (login == null || login.length() == 0) {
					final eAdvancedMessage evm = eAdvancedMessage.main(eMessageType.ERROR);
					evm.setMessageTitle("Invalid login!");
					evm.setWindowTitle("Login failed!");
					evm.setMessage("The login field is blank.");
					evm.waitForOK();
					textField.setEnabled(true);
					passwordField.setEnabled(true);
					textField_1.setText("");
					eLoginPane.this.generateCaptcha();
					btnLogin.setEnabled(true);
					btnExit.setEnabled(true);
					textField_1.setEnabled(true);
					return;
				}
				final String password = new String(passwordField.getPassword());
				if (password == null || password.length() == 0) {
					final eAdvancedMessage evm = eAdvancedMessage.main(eMessageType.ERROR);
					evm.setMessageTitle("Invalid password!");
					evm.setWindowTitle("Login failed!");
					evm.setMessage("The password field is blank.");
					evm.waitForOK();
					textField.setEnabled(true);
					passwordField.setEnabled(true);
					textField_1.setText("");
					eLoginPane.this.generateCaptcha();
					btnLogin.setEnabled(true);
					btnExit.setEnabled(true);
					textField_1.setEnabled(true);
					return;
				}
				if (eLoginPane.this.useCaptcha) {
					if (captchaInput == null || captchaInput.length() == 0) {
						final eAdvancedMessage evm = eAdvancedMessage.main(eMessageType.ERROR);
						evm.setMessageTitle("Captcha incomplete!");
						evm.setWindowTitle("Login failed!");
						evm.setMessage("The captcha is required to login.");
						evm.waitForOK();
						textField.setEnabled(true);
						passwordField.setEnabled(true);
						textField_1.setText("");
						eLoginPane.this.generateCaptcha();
						btnLogin.setEnabled(true);
						btnExit.setEnabled(true);
						textField_1.setEnabled(true);
						return;
					}else {
						if (!ArrayUtils.StringArrayUtils.contains(eLoginPane.this.acceptedCaptchaVars, captchaInput)) {
							final eAdvancedMessage evm = eAdvancedMessage.main(eMessageType.ERROR);
							evm.setMessageTitle("Captcha failed!");
							evm.setWindowTitle("Login failed!");
							evm.setMessage("Invalid captcha data entered.");
							evm.waitForOK();
							textField.setEnabled(true);
							passwordField.setEnabled(true);
							textField_1.setText("");
							eLoginPane.this.generateCaptcha();
							textField_1.setEnabled(true);
							btnLogin.setEnabled(true);
							btnExit.setEnabled(true);
							return;
						}
					}
				}
				if (eLoginPane.this.events == null) {
					final eAdvancedMessage evm = eAdvancedMessage.main(eMessageType.ERROR);
					evm.setMessageTitle("Internal error");
					evm.setWindowTitle("Login failed!");
					evm.setMessage("An internal error occured.");
					evm.waitForOK();
					textField.setEnabled(true);
					passwordField.setEnabled(true);
					textField_1.setText("");
					eLoginPane.this.generateCaptcha();
					textField_1.setEnabled(true);
					btnLogin.setEnabled(true);
					btnExit.setEnabled(true);
					return;
				}
				final boolean result = eLoginPane.this.events.loginAttempt(login, password);
				if (!result) {
					final eAdvancedMessage evm = eAdvancedMessage.main(eMessageType.ERROR);
					evm.setMessageTitle("Unable to login");
					evm.setWindowTitle("Login failed!");
					evm.setMessage("Failed to login, try again.");
					evm.waitForOK();
					textField.setEnabled(true);
					passwordField.setEnabled(true);
					textField_1.setText("");
					eLoginPane.this.generateCaptcha();
					textField_1.setEnabled(true);
					btnLogin.setEnabled(true);
					btnExit.setEnabled(true);
					return;
				}else {
					eLoginPane.this.setVisible(false);
					eLoginPane.this.dispose();
					eLoginPane.this.events.loginPassoff(login);
				}
			}
		});
		
		btnExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				System.exit(-1);
			}
		});
		GroupLayout gl_contentPane = new GroupLayout(contentPane);
		gl_contentPane.setHorizontalGroup(
			gl_contentPane.createParallelGroup(Alignment.TRAILING)
				.addGroup(gl_contentPane.createSequentialGroup()
					.addContainerGap()
					.addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
						.addComponent(panel, GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
						.addComponent(textField, GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
						.addComponent(lblUsername)
						.addComponent(lblPassword)
						.addComponent(passwordField, GroupLayout.DEFAULT_SIZE, 335, Short.MAX_VALUE)
						.addComponent(lblEloginpaneproducticon)
						.addGroup(gl_contentPane.createSequentialGroup()
							.addComponent(btnExit, GroupLayout.DEFAULT_SIZE, 144, Short.MAX_VALUE)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(btnLogin, GroupLayout.DEFAULT_SIZE, 179, Short.MAX_VALUE)))
					.addContainerGap())
		);
		gl_contentPane.setVerticalGroup(
			gl_contentPane.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_contentPane.createSequentialGroup()
					.addGap(40)
					.addComponent(lblEloginpaneproducticon)
					.addGap(18)
					.addComponent(lblUsername)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(textField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(lblPassword)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(passwordField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addComponent(panel, GroupLayout.DEFAULT_SIZE, 136, Short.MAX_VALUE)
					.addPreferredGap(ComponentPlacement.RELATED)
					.addGroup(gl_contentPane.createParallelGroup(Alignment.BASELINE)
						.addComponent(btnExit)
						.addComponent(btnLogin))
					.addContainerGap())
		);
		panel.setLayout(new BorderLayout(0, 0));
		
		textField_1 = new JTextField();
		panel.add(textField_1, BorderLayout.SOUTH);
		textField_1.setColumns(10);
		
		JScrollPane scrollPane = new JScrollPane();
		panel.add(scrollPane, BorderLayout.CENTER);
		
		editorPane = new JEditorPane();
		scrollPane.setViewportView(editorPane);
		editorPane.setEditable(false);
		editorPane.setContentType("text/html");
		editorPane.setEditorKit(new FastEditorKit());
		
		JLabel lblCaptcha = new JLabel("Captcha");
		scrollPane.setColumnHeaderView(lblCaptcha);
		contentPane.setLayout(gl_contentPane);
		
		panel_1 = new JPanel();
		contentPane0.add(panel_1, BorderLayout.NORTH);
		panel_1.setLayout(new BorderLayout(0, 0));
		
		panel_2 = new iNotify();
		panel_2.setBackground(this.getBackground());
		panel_1.add(panel_2, BorderLayout.CENTER);
	}
	
	protected JEditorPane getEditorPane() {
		return editorPane;
	}
	
	private boolean useCaptcha;
	private String[] acceptedCaptchaVars;
	private JPanel panel;
	private JLabel lblEloginpaneproducticon;
	private JPanel panel_1;
	private iNotify panel_2;
	public void generateCaptcha() {
		panel.setEnabled(true);
		panel.setVisible(true);
		this.useCaptcha = true;
		final Captcha cap = nCaptcha.randomCaptcha();
		final DataSet<String, String[]> data = cap.generateBase64Image(0);
		editorPane.setText("<html><head><img src=\"" + data.getA() + "\"><p>" + nCaptcha.translateFromType(cap.getType()) + "</p></head></html>");
		this.acceptedCaptchaVars = data.getB();
	}
	
	protected JPanel getCaptchaPanel() {
		return panel;
	}
	
	public JLabel getProductIconSlot() {
		return lblEloginpaneproducticon;
	}
	
	public boolean add(final Message message) {
		return this.panel_2.addMessage(message);
	}
}
